/****************************************************************************************************************************************************************
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *                      _____  ___________                   ___    ______      ______           _____     _______________________                              *
 *                      __  / / /__  /_  /_____________ _    __ |  / /__(_)________  /_____________  /_    ___    |_____/_/__  __ \                             *
 *                      _  / / /__  /_  __/_  ___/  __ `/    __ | / /__  /_  __ \_  /_  _ \_  __ \  __/    __  /| |___/_/ __  / / /                             *
 *                      / /_/ / _  / / /_ _  /   / /_/ /     __ |/ / _  / / /_/ /  / /  __/  / / / /_      _  ___ |_/_/   _  /_/ /                              *
 *                      \____/  /_/  \__/ /_/    \__,_/      _____/  /_/  \____//_/  \___//_/ /_/\__/      /_/  |_/_/     /_____/                               *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *      @Project: Ultra Violent - Attack and Defend                                                                                                             *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *      @Author: Daniel "thiaZ" Koenen                                                                                                                          *
 *          @Used content                                                                                                                                       *
 *              @sscanf Plugin, foreach, Whirlpool Plugin, YSI - Y_Less                                                                                         *
 *              @zcmd - Zeex                                                                                                                                    *
 *              @Streamer Plugin, IRC Plugin - Incognito                                                                                                        *
 *              @dini - Dracoblue                                                                                                                               *
 *              @MySQL Plugin - G-sTyLeZzZ                                                                                                                      *
 *          @Special thanks to                                                                                                                                  *
 *              @Slice                                                                                                                                          *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *      @File: uvaad.pwn - Main File                                                                                                                            *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *      @This file is not released under any open source licence, you are not allowed to own this file except you have the author's permission.                 *
 *                                                                                                                                                              *
 *                                                                                                                                                              *
 *      @copyright (c) Daniel "thiaZ" Koenen 2010 - 2011 - danielkoenen@t-online.de                                                                             *
 *                                                                                                                                                              *
 ****************************************************************************************************************************************************************/          

Hook:CArena_OnGameModeInit()
{
    CArena::load();
    return true;
}

Hook:CArena_OnPlayerDeath(playerId, killerId, reason)
{
    if(!gameData[bIsRoundActive] || !gameData[bIsArena])
    {
        return true;
    }
    
    if(playerData[playerId][isPlaying] && IsPlayerConnected(killerId))
    {
        RemovePlayerMapIcon(playerId, ARENA_ICON_H_ID);
        RemovePlayerMapIcon(playerId, ARENA_ICON_A_ID);
                
        statsInfo[playerId][iRoundDeaths]++;
        statsInfo[playerId][iSessionDeaths]++;
        statsInfo[playerId][iCWDeaths]++;
        
        statsInfo[killerId][iRoundKills]++;
        statsInfo[killerId][iSessionKills]++;
        statsInfo[killerId][iCWKills]++;
        
        playerData[playerId][isPlaying] = false;
        
        if(playerData[playerId][team] == TEAM_HOME) 
        {
            gameData[iPlayingHome]--;
        }
                
        if(playerData[playerId][team] == TEAM_AWAY) 
        {
            gameData[iPlayingAway]--;
        }   
        
        if(!CArena::getActivePlayers(playerData[playerId][team]))
        {
            if(playerData[playerId][team] == TEAM_HOME)
            {
                CArena::endArena(CASE_AWAYWIN);
            }
            
            if(playerData[playerId][team] == TEAM_AWAY)
            {
                CArena::endArena(CASE_HOMEWIN);
            }
        }
    }
    
    return true;
}

Hook:CArena_OnPlayerDisconnect(playerId, reason)
{
    if(!gameData[bIsRoundActive] || !gameData[bIsArena])
    {
        return true;
    }
    
    if(playerData[playerId][isPlaying])
    {
        playerData[playerId][isPlaying] = false;
        
        if(!CArena::getActivePlayers(playerData[playerId][team]))
        {
            if(playerData[playerId][team] == TEAM_HOME)
            {
                CArena::endArena(CASE_AWAYWIN);
            }
            
            if(playerData[playerId][team] == TEAM_AWAY)
            {
                CArena::endArena(CASE_HOMEWIN);
            }
        }
    }
    
    return true;
}

stock CArena::iterator()
{
    for (new i; i < MAX_ARENAS; i++) { 
        if(!arenaData[i][bIsValid])
            break;
        
        if(arenaData[i][aInterior] > 0)
            Iter_Add(IntArenas, i);
        
        else
            Iter_Add(Arenas, i);
    }
    
    return;
}

stock CArena::load()
{
    for(new i = 0; i < MAX_ARENAS; i++)
    {
        if(!fexist(CArena::getFile(i)))
        {
            #if DEBUG == true
                printf("[Arena] [%d] File does not exist, aborting. (%s)", i, CDM::getFile(i));
            #endif
            break;
        }
        
        INI_ParseFile(CArena::getFile(i), "onArenaLoad", false, true, i, true, false);
    }
    
    CArena::iterator();
    return true;
}

forward onArenaLoad(i, name[], value[]);
public  onArenaLoad(i, name[], value[])
{   
    if(!strcmp(name, "interior"))
    {
        arenaData[i][aInterior] = strval(value);
        return true;
    }
    
    if(!strcmp(name, "home"))
    {
        sscanf(value, "p<,>ffff", arenaData[i][hSpawns][0], arenaData[i][hSpawns][1], arenaData[i][hSpawns][2], arenaData[i][hSpawns][3]);
        arenaData[i][bIsValid] = true;
        return true;
    }
    
    if(!strcmp(name, "away"))
    {
        sscanf(value, "p<,>ffff", arenaData[i][aSpawns][0], arenaData[i][aSpawns][1], arenaData[i][aSpawns][2], arenaData[i][aSpawns][3]);
        return true;
    }
    
    if(!strcmp(name, "cam"))
    {
        sscanf(value, "p<,>fff", arenaData[i][aCam][0], arenaData[i][aCam][1], arenaData[i][aCam][2]);
        return true;
    }
    
    #if DEBUG == true
        printf("[Arena] [%d] %s with value %s.", i, name, value);
    #endif
    
    return true;
}

stock CArena::getFile(iArena) 
{
    new _sPath[64];
    format(_sPath, 64, "/Uv_AAD/Arenas/%d.ini", iArena);
    return _sPath;
}

forward alias_prepareArena(iArena, bool:bFirst);
public alias_prepareArena(iArena, bool:bFirst) { CArena::prepareArena(iArena, bFirst); }

stock CArena::prepareArena(iArena, bool:bFirst)
{
    if(bFirst)
    {
        gameData[iPrepareTime] = gameConfig[iPrepareTime];
        
        loop_players(playerId)
        {
            if(playerData[playerId][team] == TEAM_HOME)
            {
                SetPlayerPos(playerId, arenaData[iArena][hSpawns][0], arenaData[iArena][hSpawns][1], arenaData[iArena][hSpawns][2]);
                SetPlayerFacingAngle(playerId, arenaData[iArena][hSpawns][3]);
            }
            
            else if(playerData[playerId][team] == TEAM_AWAY)
            {
                SetPlayerPos(playerId, arenaData[iArena][aSpawns][0], arenaData[iArena][aSpawns][1], arenaData[iArena][aSpawns][2]);
                SetPlayerFacingAngle(playerId, arenaData[iArena][aSpawns][3]);
            }
         
            TogglePlayerControllable(playerId, false);
            SetPlayerVirtualWorld(playerId, ARENA_WORLD);
            
            SetPlayerCameraPos(playerId, arenaData[iArena][aCam][0], arenaData[iArena][aCam][1], arenaData[iArena][aCam][2]);
            SetPlayerCameraLookAt(playerId, arenaData[iArena][hSpawns][0], arenaData[iArena][hSpawns][1], arenaData[iArena][hSpawns][2]);
            
            CPlayer::setPlayerHP(playerId, 200.0);
            ResetPlayerWeapons(playerId);
            GivePlayerWeapon(playerId, 24, 9999);
            GivePlayerWeapon(playerId, 25, 9999);
            GivePlayerWeapon(playerId, 29, 9999);
            GivePlayerWeapon(playerId, 31, 9999);
            GivePlayerWeapon(playerId, 34, 9999);
            
            TextDrawShowForPlayer(playerId, textDraw[prepareTime]);
            
            playerData[playerId][activeDM] = -1;
                
            playerData[playerId][isDMSpawn] = false;
            playerData[playerId][isPlaying] = true;
        }
                
        CArena::prepareArena(iArena, false);
        return true;
    }
    
    if(gameData[iPrepareTime] > 0) 
    {
        gameData[iPrepareTime]--;
            
        new szTextDrawString[128];
        format(szTextDrawString, 128, "~g~~h~Arena %d~w~ starts in ~p~~h~%02d ~w~ seconds", iArena, gameData[iPrepareTime]);
        TextDrawSetString(textDraw[prepareTime], szTextDrawString);
        SetTimerEx("alias_prepareArena", 1000, 0, "db", iArena, false);
        return true;
    }
        
    else if(gameData[iPrepareTime] == 0) 
    {
        CArena::startArena(iArena);
        TextDrawHideForAll(textDraw[prepareTime]);
        return true;
    }

    return true;
}

stock CArena::startArena(iArena)
{
    new szMap[32];
    format(szMap, 32, "mapname Arena #%02d", iArena);
    SendRconCommand(szMap);
    
    gameData[iPlayingHome] = 0;
    gameData[iPlayingAway] = 0;
    
    loop_players(playerId) 
    {
        if(playerData[playerId][isPlaying] == true) 
        {
            SetCameraBehindPlayer(playerId);
            SetPlayerHealth(playerId, 100.0);
            SetPlayerArmour(playerId, 100.0);
            TogglePlayerControllable(playerId, true);
            CPlayer::UpdatePlayerColor(playerId);
            
            SetPlayerMapIcon(playerId, ARENA_ICON_H_ID, arenaData[iArena][aSpawns][0], arenaData[iArena][aSpawns][1], arenaData[iArena][aSpawns][2], 23, 0, MAPICON_GLOBAL);
            SetPlayerMapIcon(playerId, ARENA_ICON_A_ID, arenaData[iArena][hSpawns][0], arenaData[iArena][hSpawns][1], arenaData[iArena][hSpawns][2], 23, 0, MAPICON_GLOBAL);
            
            if(playerData[playerId][team] == TEAM_HOME) 
            {
                gameData[iPlayingHome]++;
            }
            
            if(playerData[playerId][team] == TEAM_AWAY) 
            {
                gameData[iPlayingAway]++;
            }
        }
    }
    
    gameData[iCurBase] = iArena;
    
    gameData[bIsArena] = true;
    gameData[bIsRoundActive] = true;
    gameData[bFirstBlood] = false;
    
    gameData[iTotalHome] = gameData[iPlayingHome];
    gameData[iTotalAway] = gameData[iPlayingAway];
    
    alias_updateArenaTextDraw(true);
    HidePlayersFromOtherPlayers();
    return true;
}

forward alias_updateArenaTextDraw(bool:bFirst);
public alias_updateArenaTextDraw(bool:bFirst)
{
    if(!gameData[bIsRoundActive]) 
    {
        return true;
    }

    if(bFirst)
    {
        new szTeamName[15];
        SetProgressBarColor(textDraw[healthBar][TEAM_HOME], C_DEF);
        SetProgressBarColor(textDraw[healthBar][TEAM_AWAY], C_ATT);
                    
        format(szTeamName, 15, "%s~h~%s~w~:", DEF_TAG, gameConfig[homeName]);
        TextDrawSetString(textDraw[barDes][TEAM_HOME], szTeamName);
                    
        format(szTeamName, 15, "%s~h~%s~w~:", ATT_TAG, gameConfig[awayName]);
        TextDrawSetString(textDraw[barDes][TEAM_AWAY], szTeamName);
            
        TextDrawColor(textDraw[healLost][TEAM_HOME], C_DEF);
        TextDrawColor(textDraw[healLost][TEAM_AWAY], C_ATT);
                
        foreach(Player, playerId) 
        {
            if(playerData[playerId][isPlaying] == true) 
            {
                CPlayer::HideLobbyDraws(playerId);
                
                TextDrawShowForPlayer(playerId, textDraw[baseInfo]);
                TextDrawShowForPlayer(playerId, textDraw[barDes][TEAM_HOME]);
                TextDrawShowForPlayer(playerId, textDraw[barDes][TEAM_AWAY]);
                TextDrawShowForPlayer(playerId, textDraw[healLost][TEAM_HOME]);
                TextDrawShowForPlayer(playerId, textDraw[healLost][TEAM_AWAY]);
                
                ShowProgressBarForPlayer(playerId, textDraw[healthBar][TEAM_HOME]);
                ShowProgressBarForPlayer(playerId, textDraw[healthBar][TEAM_AWAY]);
            }
        }
    }
    
    new HomePlayers,
        AwayPlayers,
        Float:HomeHealth,
        Float:AwayHealth,
        Float:HomePercent,
        Float:AwayPercent,
        Float:plHealth,
        Float:plArmour,
        szTextDraw[512];
        
    gameData[fHomeHealth] = 0.0;
    gameData[fAwayHealth] = 0.0;
        
    loop_players(playerId) 
    {
        if(playerData[playerId][team] == TEAM_HOME && playerData[playerId][isPlaying] == true) 
        {
            GetPlayerHealth(playerId, plHealth);
            GetPlayerArmour(playerId, plArmour);
            gameData[fHomeHealth] += (plHealth + plArmour);
        }
            
        if(playerData[playerId][team] == TEAM_AWAY && playerData[playerId][isPlaying] == true) 
        {
            GetPlayerHealth(playerId, plHealth);
            GetPlayerArmour(playerId, plArmour);
            gameData[fAwayHealth] += (plHealth + plArmour);
        }
    }
            
            
    HomePlayers = gameData[iPlayingHome];
    AwayPlayers = gameData[iPlayingAway];
    HomeHealth = gameData[fHomeHealth];
    AwayHealth = gameData[fAwayHealth];
    HomePercent = ((gameData[fHomeHealth]) / (gameData[iTotalHome] * 200) * 100);
    AwayPercent = ((gameData[fAwayHealth]) / (gameData[iTotalAway] * 200) * 100);
        
    SetProgressBarMaxValue(textDraw[healthBar][TEAM_HOME], (gameData[iTotalHome] * 200));
    SetProgressBarMaxValue(textDraw[healthBar][TEAM_AWAY], (gameData[iTotalAway] * 200));
        
    SetProgressBarValue(textDraw[healthBar][TEAM_HOME], floatround(HomeHealth));
    SetProgressBarValue(textDraw[healthBar][TEAM_AWAY], floatround(AwayHealth));
        
    UpdateProgressBar(textDraw[healthBar][TEAM_HOME]);
    UpdateProgressBar(textDraw[healthBar][TEAM_AWAY]);
        
    format(szTextDraw, 512, "%s~h~%s :: %d/%d :: %.0f/%.0f :: %.0f%%                                                  %s~h~%s :: %d/%d :: %.0f/%.0f :: %.0f%%", DEF_TAG, 
                                                                                                                                                                gameConfig[homeName],
                                                                                                                                                                HomePlayers,
                                                                                                                                                                gameData[iTotalHome],
                                                                                                                                                                HomeHealth,
                                                                                                                                                                (gameData[iTotalHome] * 200.0),
                                                                                                                                                                HomePercent,
                                                                                                                                                                ATT_TAG,
                                                                                                                                                                gameConfig[awayName],
                                                                                                                                                                AwayPlayers,
                                                                                                                                                                gameData[iTotalAway],
                                                                                                                                                                AwayHealth,
                                                                                                                                                                (gameData[iTotalAway] * 200.0),
                                                                                                                                                                AwayPercent);
                                                                                                                                                            
    TextDrawSetString(textDraw[baseInfo], szTextDraw);
    
    if(gameData[bIsRoundActive]) 
    {
        SetTimerEx("alias_updateArenaTextDraw", 2000, 0, "b", false);
    }
    
    return true;
}

stock CArena::getActivePlayers(iPTeam)
{
    new iPlayers;
    
    if(gameData[bIsRoundActive] && gameData[bIsArena])
    {
        loop_players(playerId)
        {
            if(playerData[playerId][isPlaying] && playerData[playerId][team] == iPTeam)
            {
                iPlayers++;
            }
        }
    }
    
    return iPlayers;
}

stock CArena::endArena(iCase)
{
    switch(iCase) 
    {
        case CASE_ADMINEND: 
        {
            gameData[bIsRoundActive] = false;
        }
        
        case CASE_HOMEWIN: 
        {
            loop_players(playerId) 
            {
                if(playerData[playerId][team] == TEAM_HOME) 
                {
                    playerData[playerId][basesWon]++;
                }
                    
                else 
                {
                    playerData[playerId][basesLost]++;
                }
            }
            
            teamData[TEAM_HOME][iTeamScore]++;
            SendFormattedMessageToAll(C_GOLD, "* %s has won this arena.", gameConfig[homeName]);
            SendFormattedMessageToAll(C_GOLD, "* Scores: %d to %d (Round %d of %d)", teamData[TEAM_HOME][iTeamScore], teamData[TEAM_AWAY][iTeamScore], (teamData[TEAM_HOME][iTeamScore] + teamData[TEAM_AWAY][iTeamScore]), gameConfig[iMaxScore]);
            
            CArena::SetUpScoreTexts(iCase);
        }
        
        case CASE_AWAYWIN: 
        {
            loop_players(playerId) 
            {
                if(playerData[playerId][team] == TEAM_AWAY) 
                {
                    playerData[playerId][basesWon]++;
                }
                    
                else 
                {
                    playerData[playerId][basesLost]++;
                }
            }
            
            teamData[TEAM_AWAY][iTeamScore]++;
            SendFormattedMessageToAll(C_GOLD, "* %s has won this arena.", gameConfig[awayName]);
            SendFormattedMessageToAll(C_GOLD, "* Scores: %d to %d (Round %d of %d)", teamData[TEAM_HOME][iTeamScore], teamData[TEAM_AWAY][iTeamScore], (teamData[TEAM_HOME][iTeamScore] + teamData[TEAM_AWAY][iTeamScore]), gameConfig[iMaxScore]);
            
            CArena::SetUpScoreTexts(iCase);
        }
    }
    
    TextDrawHideForAll(textDraw[baseInfo]);
    TextDrawHideForAll(textDraw[barDes][TEAM_HOME]);
    TextDrawHideForAll(textDraw[barDes][TEAM_AWAY]);
    TextDrawHideForAll(textDraw[healLost][TEAM_HOME]);
    TextDrawHideForAll(textDraw[healLost][TEAM_AWAY]);
    HideProgressBarForAll(textDraw[healthBar][TEAM_HOME]);
    HideProgressBarForAll(textDraw[healthBar][TEAM_AWAY]);
        
    loop_players(playerId) 
    {
        CPlayer::ShowLobbyDraws(playerId);
        SetPlayerTeam(playerId, NO_TEAM);
        
        if(playerData[playerId][isSpectating] == true)
        {
            printf("Player %d is spectating.", playerId);
            CPlayer::Unspectate(playerId);
            printf("Aborted!");
        }
        
        CPlayer::UpdatePlayerColor(playerId);
        
        if(playerData[playerId][isPlaying] == true) 
        {
            playerData[playerId][isPlaying] = false;
            RemovePlayerMapIcon(playerId, ARENA_ICON_H_ID);
            RemovePlayerMapIcon(playerId, ARENA_ICON_A_ID);
            
            if(playerData[playerId][isSpawned] == true) 
            {
                CPlayer::SpawnEx(playerId);
            }
        }
    }
    
    gameData[bIsRoundActive] = false;
    gameData[bIsArena] = false;
    gameData[bIsPaused] = false;
    CBase::CheckTeamScore();
    hookIRC("onGameEnd", "iisii", 0, iCase, (iCase == CASE_HOMEWIN) ? (gameConfig[homeName]) : (gameConfig[awayName]), teamData[TEAM_HOME][iTeamScore], teamData[TEAM_AWAY][iTeamScore]);
    
    SendRconCommand("mapname Lobby");
    return true;
}
                
stock CArena::SetUpScoreTexts(iCaseId) 
{
    new szTempHome[1024],
        szTempAway[1024],
        szHomeText[64],
        szAwayText[64],
        szStatDes[128],
        iCH,
        iCA;
        
    loop_players(playerId) 
    {
        if(playerData[playerId][team] == TEAM_HOME) 
        {
            iCH++;
            if(iCH == 1) 
            {
                format(szTempHome, 1024, "%s (%d)~n~", CPlayer::getName(playerId),
                                                       statsInfo[playerId][iRoundKills]);
            }
            
            else 
            {
                format(szTempHome, 1024, "%s%s (%d)~n~", szTempHome,
                                                        CPlayer::getName(playerId),
                                                        statsInfo[playerId][iRoundKills]);
            }
        }
        
        if(playerData[playerId][team] == TEAM_AWAY) 
        {
            iCA++;
            if(iCA == 1) 
            {
                format(szTempAway, 1024, "%s (%d)~n~", CPlayer::getName(playerId),
                                                       statsInfo[playerId][iRoundKills]);
            }
            
            else 
            {
                format(szTempAway, 1024, "%s%s (%d)~n~", szTempAway,
                                                        CPlayer::getName(playerId),
                                                        statsInfo[playerId][iRoundKills]);
            }
        }
    }
    
    switch(iCaseId) 
    {
        case CASE_HOMEWIN: 
        {
            format(szStatDes, 128, "Arena: #%d    /     Winner: %s~h~%s    ~w~/    MVP: %s", gameData[iCurBase], DEF_TAG, gameConfig[homeName], CArena::getMVP());
        }
        
        case CASE_AWAYWIN: 
        {
            format(szStatDes, 128, "Arena: #%d    /     Winner: %s~h~%s    ~w~/    MVP: %s", gameData[iCurBase], ATT_TAG, gameConfig[awayName], CArena::getMVP());
        }
    }
    
    format(szHomeText, 64, "%s~h~%s", DEF_TAG, gameConfig[homeName]);
    format(szAwayText, 64, "%s~h~%s", ATT_TAG, gameConfig[awayName]);
    
    TextDrawSetString(textDraw[homePlayers], szTempHome);
    TextDrawSetString(textDraw[awayPlayers], szTempAway);
    TextDrawSetString(textDraw[statDes], szStatDes);
    TextDrawSetString(textDraw[scoreboard_Home], szHomeText);
    TextDrawSetString(textDraw[scoreboard_Away], szAwayText);
    
    TextDrawShowForAll(textDraw[homePlayers]);
    TextDrawShowForAll(textDraw[awayPlayers]);
    TextDrawShowForAll(textDraw[statDes]);
    TextDrawShowForAll(textDraw[scoreboard_Home]);
    TextDrawShowForAll(textDraw[scoreboard_Away]);
    
    SetTimer("alias_HideArenaScoreBoard", 7500, false);
    
    loop_players(playerId) 
    {
        statsInfo[playerId][iRoundKills] = 0;
    }
}

forward alias_HideArenaScoreBoard();
public alias_HideArenaScoreBoard() 
{
    CArena::HideScoreBoard();
    return true;
}

stock CArena::HideScoreBoard() 
{
    TextDrawHideForAll(textDraw[homePlayers]);
    TextDrawHideForAll(textDraw[awayPlayers]);
    TextDrawHideForAll(textDraw[statDes]);
    TextDrawHideForAll(textDraw[scoreboard_Home]);
    TextDrawHideForAll(textDraw[scoreboard_Away]);
    return true;
}   

stock CArena::getMVP() 
{
    new mvpKills,
        playerId,
        szResult[32];
        
    loop_players(playerid) 
    {
        if(statsInfo[playerid][iRoundKills] >= mvpKills) 
        {
            mvpKills = statsInfo[playerid][iRoundKills];
            playerId = playerid;
        }
    }
    
    hookIRC("onPickMVP", "si", nickName(playerId), mvpKills);
    playerData[playerId][mvp]++;
    format(szResult, 32, "%s (%d)", CPlayer::getName(playerId), mvpKills);
    return szResult;
}       
    